#include "SemanticNodeNamespace.h"

#include "SemanticNodeEnum.h"
#include "SemanticNodeClass.h"
#include "SemanticNodeSimulation.h"
#include "SemanticNodeModel.h"
#include "SemanticNodeMethod.h"
#include "SemanticNodeProperty.h"
#include "UsingDirectives.h"

//TODO brisi
#include "main2.h"


SemanticNodeNamespace::SemanticNodeNamespace(const SyntaxTreeNode &syntaxNode, SemanticNode *parentNode) :	SemanticNode(parentNode) {
	if (syntaxNode.Production == Gr_GppFile__UsingDirectives_FileBody_endOfFile) {
		name = "";
		usingDirectives = new UsingDirectives(syntaxNode.Nodes->GetData(0), this);
	} else if (syntaxNode.Production == Gr_NamespaceDefinition__namespace_Name_spLCBrac_UsingDirectives_FileBody_spRCBrac) {
		name = flattenNamePeriodAdd(*syntaxNode.Nodes->GetData(1));
		usingDirectives = new UsingDirectives(syntaxNode.Nodes->GetData(3), this);
	} else {	/* ovo se nesmije desit */	}

	int fbIndex = 1;
	if (syntaxNode.Production == Gr_NamespaceDefinition__namespace_Name_spLCBrac_UsingDirectives_FileBody_spRCBrac) fbIndex = 4;
	SyntaxTreeNode *fileBodyNode = syntaxNode.Nodes->GetData(fbIndex);
	for (int i = 0; i < fileBodyNode->Nodes->GetCount(); ++i) {
//		hrvoje: mislim da se ova produkcija nikada dogoditi
//		if (fileBodyNode->Production == Gr_FileBody__Simulation_FileBody) {
//			//TODO
//		} else
		if (fileBodyNode->Production == Gr_FileBody__MainDefinition_FileBody) {
			SyntaxTreeNode *mainDefNode = fileBodyNode->Nodes->GetData(i);
			switch(mainDefNode->Production) {
			case Gr_Simulation__simulation_NAME_spLCBrac_SimulationBody_spRCBrac:
				simulations.push_back(new SemanticNodeSimulation(mainDefNode, this));
				break;
			case Gr_MainDefinition__NamespaceDefinition:
				namespaces.push_back(new SemanticNodeNamespace(*(mainDefNode->Nodes->GetData(0)), this));
				break;
			case Gr_MainDefinition__EnumDefinition:
				enums.push_back(new SemanticNodeEnum(*(mainDefNode->Nodes->GetData(0)), this));
				break;
			case Gr_MainDefinition__FieldDefinition:
				{
					std::vector<SemanticNodeField *> tempFields = SemanticNodeField::analyzeNodeField(mainDefNode->Nodes->GetData(0), this);
					for (std::vector<SemanticNodeField *>::iterator i = tempFields.begin(); i != tempFields.end(); ++i) {
						fields.push_back(*i);
					}
				}
				break;
			case Gr_MainDefinition__MethodDefinition:
				methods.push_back(new SemanticNodeMethod(mainDefNode->Nodes->GetData(0), this));
				break;
			case Gr_MainDefinition__ModelDefinition:
				models.push_back(OurSemanticAnalyzer::analyzeNodeModel(mainDefNode->Nodes->GetData(0), this));
				break;
			case Gr_MainDefinition__PropertyDefinition:
				properties.push_back(new SemanticNodeProperty(mainDefNode->Nodes->GetData(0), this));
				break;
			case Gr_MainDefinition__ClassDefinition:
				classes.push_back(OurSemanticAnalyzer::analyzeNodeClass(mainDefNode->Nodes->GetData(0), this));
				break;
			default:
				// ToDo: Error (ne smije se dogoditi)
				break;
			}
		} else {
			// ToDo: Error (ne smije se dogoditi)
		}
	}

}

SemanticNodeNamespace::~SemanticNodeNamespace() {
	delete usingDirectives;
}






std::string SemanticNodeNamespace::toDebugString(int tab) {
	std::ostringstream ss;
	for (int i = 0; i < tab; i++) ss << DEBUG_STRING_RAZMAK;
	ss << "namespace " << (name != "" ? name : "(bez imena)") << std::endl;

	ss << usingDirectives->toDebugString(tab + 1);

	for (int i = 0; i < tab + 1; i++) ss << DEBUG_STRING_RAZMAK;
	ss << "Simulations: {" << std::endl;
	for (std::vector<SemanticNodeSimulation *>::iterator i = simulations.begin(); i != simulations.end(); ++i) ss << (*i)->toDebugString(tab + 2);
	for (int i = 0; i < tab + 1; i++) ss << DEBUG_STRING_RAZMAK;
	ss << "}" << std::endl;

	for (int i = 0; i < tab + 1; i++) ss << DEBUG_STRING_RAZMAK;
	ss << "Methods: {" << std::endl;
	for (std::vector<SemanticNodeMethod *>::iterator i = methods.begin(); i != methods.end(); ++i) ss << (*i)->toDebugString(tab + 2);
	for (int i = 0; i < tab + 1; i++) ss << DEBUG_STRING_RAZMAK;
	ss << "}" << std::endl;

	for (int i = 0; i < tab + 1; i++) ss << DEBUG_STRING_RAZMAK;
	ss << "Enums: {" << std::endl;
	for (std::vector<SemanticNodeEnum *>::iterator i = enums.begin(); i != enums.end(); ++i) ss << (*i)->toDebugString(tab + 2);
	for (int i = 0; i < tab + 1; i++) ss << DEBUG_STRING_RAZMAK;
	ss << "}" << std::endl;

	for (int i = 0; i < tab + 1; i++) ss << DEBUG_STRING_RAZMAK;
	ss << "Fields: {" << std::endl;
	for (std::vector<SemanticNodeField *>::iterator i = fields.begin(); i != fields.end(); ++i) ss << (*i)->toDebugString(tab + 2);
	for (int i = 0; i < tab + 1; i++) ss << DEBUG_STRING_RAZMAK;
	ss << "}" << std::endl;

	for (int i = 0; i < tab + 1; i++) ss << DEBUG_STRING_RAZMAK;
	ss << "Namespaces: {" << std::endl;
	for (std::vector<SemanticNodeNamespace *>::iterator i = namespaces.begin(); i != namespaces.end(); ++i) ss << (*i)->toDebugString(tab + 2);
	for (int i = 0; i < tab + 1; i++) ss << DEBUG_STRING_RAZMAK;
	ss << "}" << std::endl;

	for (int i = 0; i < tab + 1; i++) ss << DEBUG_STRING_RAZMAK;
	ss << "Classes: {" << std::endl;
	for (std::vector<SemanticNodeClass *>::iterator i = classes.begin(); i != classes.end(); ++i) ss << (*i)->toDebugString(tab + 2);
	for (int i = 0; i < tab + 1; i++) ss << DEBUG_STRING_RAZMAK;
	ss << "}" << std::endl;

	for (int i = 0; i < tab + 1; i++) ss << DEBUG_STRING_RAZMAK;
	ss << "Models: {" << std::endl;
	for (std::vector<SemanticNodeModel *>::iterator i = models.begin(); i != models.end(); ++i) ss << (*i)->toDebugString(tab + 2);
	for (int i = 0; i < tab + 1; i++) ss << DEBUG_STRING_RAZMAK;
	ss << "}" << std::endl;

	for (int i = 0; i < tab + 1; i++) ss << DEBUG_STRING_RAZMAK;
	ss << "Properties: {" << std::endl;
	for (std::vector<SemanticNodeProperty *>::iterator i = properties.begin(); i != properties.end(); ++i) ss << (*i)->toDebugString(tab + 2);
	for (int i = 0; i < tab + 1; i++) ss << DEBUG_STRING_RAZMAK;
	ss << "}" << std::endl;

	return ss.str();
}

